package com.zimmur.app.mocolink.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.zimmur.app.mocolink.dao.OrderDetailMapper;
import com.zimmur.app.mocolink.dao.OrderMapper;
import com.zimmur.app.mocolink.dao.RefundOrderDetailMapper;
import com.zimmur.app.mocolink.dao.RefundOrderMapper;
import com.zimmur.app.mocolink.domain.common.Constant;
import com.zimmur.app.mocolink.domain.form.ApplyRefundForm;
import com.zimmur.app.mocolink.domain.form.RefundExpress;
import com.zimmur.app.mocolink.domain.form.UserMoneyForm;
import com.zimmur.app.mocolink.domain.model.Order;
import com.zimmur.app.mocolink.domain.model.OrderDetail;
import com.zimmur.app.mocolink.domain.model.RefundOrder;
import com.zimmur.app.mocolink.domain.model.RefundOrderDetail;
import com.zimmur.app.mocolink.domain.model.RefundOrderDetailExample;
import com.zimmur.app.mocolink.domain.model.RefundOrderExample;
import com.zimmur.app.mocolink.domain.param.RefundParam;
import com.zimmur.app.mocolink.domain.util.AppModuleEnum;
import com.zimmur.app.mocolink.domain.util.DateUtils;
import com.zimmur.app.mocolink.domain.util.IDWorkFactory;
import com.zimmur.app.mocolink.domain.util.PageUtil;
import com.zimmur.app.mocolink.domain.util.StringUtils;
import com.zimmur.app.mocolink.domain.vo.RefundOrderInfo;
import com.zimmur.app.mocolink.domain.vo.RefundOrderVo;
import com.zimmur.app.mocolink.domain.vo.RefundOrderVoForManage;
import com.zimmur.app.mocolink.service.IAppUserService;
import com.zimmur.app.mocolink.service.IRefundOrderService;
@Service
public class RefundOrderServiceImpl implements IRefundOrderService {
 
	@Autowired
	private RefundOrderMapper refundOrderMapper;
	@Autowired
	private RefundOrderDetailMapper refundOrderDetailMapper;
	@Autowired
	private OrderDetailMapper orderDetailMapper;
	@Autowired
	private OrderMapper orderMapper;
	@Autowired
	private IAppUserService appUserService;
	
	@Override
	public PageUtil<RefundOrderVo> selectByUserId(Integer userId, Integer pageNo) {
		PageUtil<RefundOrderVo> page = new PageUtil<>();
		page.setPageNo(pageNo);
		List<RefundOrderVo> list = refundOrderMapper.selectByUserId(page.getPageBeginNo(), page.getPageSize(), userId);
		int count = refundOrderMapper.countByUserId(userId);
		page.setItemList(list);
		page.setTotalRecord(count);
		return page;
	}
	@Transactional
	@Override
	public int addRefundOrder(Integer userId, String refundInfo, String summary,Order order) {
		String[] orderInfoArray = refundInfo.split(";");
		RefundOrder refundOrder = new RefundOrder();
		List<RefundOrderDetail> detailList = new ArrayList<>();
		Date nowTime = DateUtils.getNow();
		double applyJe=0;
		List<OrderDetail> orderDetailList=new ArrayList<>();
		for(String orderInfo:orderInfoArray){
			String[] info = orderInfo.split(",");
			Integer orderDetailId=Integer.valueOf(info[0]);
			Integer quantity = Integer.valueOf(info[1]);
			OrderDetail orderDetail = orderDetailMapper.selectByPrimaryKey(orderDetailId);
			if(orderDetail==null){
				return -1;
			}
			Integer refundQuantity=orderDetail.getRefundQuantity()+quantity;
			if(orderDetail.getQuantity()<refundQuantity){
				return -2;
			}
			RefundOrderDetail detail = new RefundOrderDetail();
			detail.setOrderDetailId(orderDetail.getId());
			detail.setGoodsId(orderDetail.getGoodsId());
			detail.setGoodsName(orderDetail.getGoodsName());
			detail.setColorName(orderDetail.getColorName());
			detail.setSizeName(orderDetail.getSizeName());
			detail.setCoverImage(orderDetail.getCoverImg());
			detail.setSkuName(orderDetail.getSkuCode());
			detail.setStyleCode(orderDetail.getStyleCode());
			detail.setCreateDate(nowTime);
			
			detail.setPrice(orderDetail.getPrice());
			detail.setBuyPrice(orderDetail.getBuyPrice());
			double buyPrice = orderDetail.getBuyPrice().doubleValue();
			double detailJe = buyPrice*quantity;
			applyJe+=detailJe;
			detail.setDetailJe(new BigDecimal(detailJe));
			detail.setQuantity(quantity);
			detail.setSignQuantity(0);
			detailList.add(detail);
			
			orderDetail.setRefundQuantity(refundQuantity);
			orderDetailList.add(orderDetail);
		}
		
		String refundNo ="R"+IDWorkFactory.getID(AppModuleEnum.UserOrder);
		refundOrder.setOrderId(order.getId());
		refundOrder.setRefundNo(refundNo);
		refundOrder.setUserId(userId);
		refundOrder.setApplyJe(new BigDecimal(applyJe));
		refundOrder.setStatus(Constant.Refund_Status_Wait_Check);
		refundOrder.setStatusName(Constant.Refund_Status_Wait_Check_Text);
		refundOrder.setCreateTime(nowTime);
		refundOrder.setSummary(summary);
		refundOrder.setRefundJe(new BigDecimal(0));
		int flag = refundOrderMapper.insertSelective(refundOrder);
		if(flag>0){
			int refundId=refundOrder.getId();
			for(RefundOrderDetail detail:detailList){
				detail.setRefundId(refundId);
			}
			refundOrderDetailMapper.batchInsert(detailList);
			
			for(OrderDetail orderDetail:orderDetailList){
				orderDetailMapper.updateByPrimaryKeySelective(orderDetail);
			}
		}
		
		return flag;
	}
	@Override
	public PageUtil<RefundOrderInfo> selectByParam(RefundParam param) {
		PageUtil<RefundOrderInfo> page = new PageUtil<>();
		List<RefundOrderInfo> list = refundOrderMapper.selectByParam(param);
		int count = refundOrderMapper.countByParam(param);
		page.setPageNo(param.getPageNo());
		page.setPageSize(param.getPageSize());
		page.setItemList(list);
		page.setTotalRecord(count);
		return page;
	}
	@Transactional
	@Override
	public int saveRefundInfo(ApplyRefundForm form) {
		Order order = orderMapper.selectByPrimaryKey(form.getOrderId());
		if(order==null || Constant.Order_Status_Cancel.equals(order.getStatus())
			|| Constant.Order_Status_Error.equals(order.getStatus())
			|| Constant.Order_Status_Wait_Pay.equals(order.getStatus()) ){
			return -1;
		}
		RefundOrder refundOrder = new RefundOrder();
		List<RefundOrderDetail> detailList = new ArrayList<>();
		List<OrderDetail> orderDetailList = new ArrayList<>();
		Date nowTime = DateUtils.getNow();
		double applyJe=0;
		List<OrderDetail> orderDetails = form.getOrderDetailList();
		for(OrderDetail odetail:orderDetails){
			Integer orderDetailId=odetail.getId();
			Integer quantity = odetail.getQuantity();
			OrderDetail orderDetail = orderDetailMapper.selectByPrimaryKey(orderDetailId);
			if(orderDetail==null){
				return -1;
			}
			Integer refundQuantity=orderDetail.getRefundQuantity()+quantity;
			if(orderDetail.getQuantity()<refundQuantity){
				return -2;
			}
			RefundOrderDetail detail = new RefundOrderDetail();
			detail.setOrderDetailId(orderDetail.getId());
			detail.setGoodsId(orderDetail.getGoodsId());
			detail.setGoodsName(orderDetail.getGoodsName());
			detail.setColorName(orderDetail.getColorName());
			detail.setSizeName(orderDetail.getSizeName());
			detail.setCoverImage(orderDetail.getCoverImg());
			detail.setSkuName(orderDetail.getSkuCode());
			detail.setStyleCode(orderDetail.getStyleCode());
			detail.setCreateDate(nowTime);
			
			detail.setPrice(orderDetail.getPrice());
			detail.setBuyPrice(orderDetail.getBuyPrice());
			double buyPrice = orderDetail.getBuyPrice().doubleValue();
			double detailJe = buyPrice*quantity;
			applyJe+=detailJe;
			detail.setDetailJe(new BigDecimal(detailJe));
			detail.setQuantity(quantity);
			detail.setSignQuantity(0);
			detailList.add(detail);
			
			orderDetail.setRefundQuantity(refundQuantity);
			orderDetailList.add(orderDetail);
		}
		
		String refundNo ="R"+IDWorkFactory.getID(AppModuleEnum.UserOrder);
		refundOrder.setOrderId(order.getId());
		refundOrder.setRefundNo(refundNo);
		refundOrder.setUserId(order.getUserId());
		refundOrder.setApplyJe(new BigDecimal(applyJe));
		
		refundOrder.setCreateTime(nowTime);
		refundOrder.setSummary(form.getRemark());
		refundOrder.setRefundJe(new BigDecimal(0));
		if(form.getIsSend()==Constant.Apply_Refund_Send && form.getRefundExpress()!=null){
			RefundExpress express = form.getRefundExpress();
			refundOrder.setShipCompany(express.getShipCompany());
			refundOrder.setShipNo(express.getShipNo());
			refundOrder.setShipTime(DateUtils.dateFormat(express.getShipDate(), "yyyy-MM-dd"));
		}
		if(Constant.Order_Status_Wait_Send.equals(order.getStatus())){
			refundOrder.setStatus(Constant.Refund_Status_Wait_Refund);
			refundOrder.setStatusName(Constant.Refund_Status_Wait_Refund_Text);
			order.setStatus(Constant.Order_Status_Done);
			order.setStatusName(Constant.Order_Status_Done_Text);
		}else{
			refundOrder.setStatus(Constant.Refund_Status_Wait_Check);
			refundOrder.setStatusName(Constant.Refund_Status_Wait_Check_Text);
		}
		int flag = refundOrderMapper.insertSelective(refundOrder);
		if(flag>0){
			int refundId=refundOrder.getId();
			for(RefundOrderDetail detail:detailList){
				detail.setRefundId(refundId);
			}
			refundOrderDetailMapper.batchInsert(detailList);
			
			for(OrderDetail orderDetail:orderDetailList){
				orderDetailMapper.updateByPrimaryKeySelective(orderDetail);
			}
			orderMapper.updateByPrimaryKeySelective(order);
		}
		
		return flag;
	}
	@Transactional
	@Override
	public int checkRefund(Integer refundId, Integer status, String adminName) {
		RefundOrder refundOrder = refundOrderMapper.selectByPrimaryKey(refundId);
		if(refundOrder == null || !Constant.Refund_Status_Wait_Check.equals(refundOrder.getStatus())){
			return -1;
		}
		int flag =0;
		if(status == 1){
			refundOrder.setStatus(Constant.Refund_Status_Wait_Send);
			refundOrder.setStatusName(Constant.Refund_Status_Wait_Send_Text);
			flag = refundOrderMapper.updateByPrimaryKeySelective(refundOrder);
		}else if(status == -1){
			refundOrder.setStatus(Constant.Refund_Status_Cancel);
			refundOrder.setStatusName(Constant.Refund_Status_Cancel_Text);
			flag = refundOrderMapper.updateByPrimaryKeySelective(refundOrder);
			if(flag>0){
				orderDetailMapper.updateRefundQuantityByRefund(refundId);
			}
		}
		return flag;
	}
	@Override
	public int saveRefundExpress(RefundExpress express) {
		RefundOrder refundOrder = refundOrderMapper.selectByPrimaryKey(express.getRefundId());
		if(refundOrder==null){
			return -1;
		}
		refundOrder.setShipCompany(express.getShipCompany());
		refundOrder.setShipNo(express.getShipNo());
		refundOrder.setShipTime(DateUtils.dateFormat(express.getShipDate(), "yyyy-MM-dd"));
		refundOrder.setStatus(Constant.Refund_Status_Wait_Sign);
		refundOrder.setStatusName(Constant.Refund_Status_Wait_Sign_Text);
		
		return refundOrderMapper.updateByPrimaryKeySelective(refundOrder);
	}
	@Transactional
	@Override
	public int saveRefundGoods(Integer refundId, String refundInfos) {
		RefundOrder refundOrder = refundOrderMapper.selectByPrimaryKey(refundId);
		if(refundOrder==null){
			return -1;
		}
		int refundQuantity=0;
		int signQuantity=0;
		List<RefundOrderDetail> detailList = new ArrayList<>();
		String[] refundInfoArray = refundInfos.split(";");
		for(String info:refundInfoArray){
			String[] infoArray = info.split(",");
			Integer detailId =Integer.valueOf(infoArray[0]);
			Integer quantity =Integer.valueOf(infoArray[1]);
			RefundOrderDetail detail = refundOrderDetailMapper.selectByPrimaryKey(detailId);
			if(detail!=null){
				refundQuantity+=detail.getQuantity();
				signQuantity+=quantity;
				detail.setSignQuantity(quantity);
				detail.setSignDate(DateUtils.getNow());
				detailList.add(detail);
			}else{
				return -1;
			}
		}
		int flag =0;
		if(detailList.size()>0){
			for(RefundOrderDetail detail:detailList){
				flag+=refundOrderDetailMapper.updateByPrimaryKeySelective(detail);
			}
		}
		if(signQuantity==refundQuantity && signQuantity>0){
			refundOrder.setStatus(Constant.Refund_Status_Wait_Refund);
			refundOrder.setStatusName(Constant.Refund_Status_Wait_Refund_Text);
			refundOrderMapper.updateByPrimaryKeySelective(refundOrder);
		}
		return flag;
	}
	@Transactional
	@Override
	public synchronized int refundMoney(Integer refundId, Double money,String adminName) {
		RefundOrder refundOrder = refundOrderMapper.selectByPrimaryKey(refundId);
		if(refundOrder==null || !Constant.Refund_Status_Wait_Refund.equals(refundOrder.getStatus())){
			return -1;
		}
		Order order =orderMapper.selectByPrimaryKey(refundOrder.getOrderId());
		if(order == null ){
			return -2;
		}
		double payJe = order.getPayJe()==null ?0:order.getPayJe().doubleValue();
		double refundJe = order.getRefundJe() == null ?0:order.getRefundJe().doubleValue();
		refundJe = refundJe+money;
		if(refundJe>payJe){
			return -3;
		}
		order.setRefundJe(new BigDecimal(refundJe));
		refundOrder.setRefundJe(new BigDecimal(money));
		refundOrder.setRefundTime(DateUtils.getNow());
		refundOrder.setStatus(Constant.Refund_Status_Done);
		refundOrder.setStatusName(Constant.Refund_Status_Done_Text);
		int flag = orderMapper.updateByPrimaryKeySelective(order);
		flag +=refundOrderMapper.updateByPrimaryKeySelective(refundOrder);
		if(flag>0){
			UserMoneyForm form = new UserMoneyForm();
			form.setAdminName(adminName);
			form.setAppUserId(order.getUserId());
			form.setDataId(refundId);
			form.setMoney(money);
			form.setRemark("售后退款");
			form.setType(Constant.User_Money_Refund);
			appUserService.updateMoney(form);
		}
		return flag;
	}
	@Override
	public RefundOrderVoForManage selectDetailById(Integer refundId) {
		RefundOrderVoForManage vo = refundOrderMapper.selectVoByRefundId(refundId);
		return vo;
	}
	@Override
	public RefundOrder selectById(Integer refundId) {
		return refundOrderMapper.selectByPrimaryKey(refundId);
	}
	@Transactional
	@Override
	public int saveRefund(Integer refundId, String remark, String deleteIds, String detailInfos, String adminUser) {
		RefundOrder refundOrder = refundOrderMapper.selectByPrimaryKey(refundId);
		if(refundOrder==null || Constant.Refund_Status_Cancel.equals(refundOrder.getStatus()) ||
		   Constant.Refund_Status_Done.equals(refundOrder.getStatus()) || Constant.Refund_Status_Wait_Refund.equals(refundOrder.getStatus())){
			return -1;
		}
		if(!StringUtils.isBlank(deleteIds)){
			String[] deleteIdArray = deleteIds.split(",");
			
			List<Integer> deleteIdList = new ArrayList<>();
			for(String deleteId:deleteIdArray){
				deleteIdList.add(Integer.valueOf(deleteId));
			}
			if(deleteIdList.size()>0){
				orderDetailMapper.updateRefundQuantityByRefundDetail(deleteIdList, refundId);
				
				RefundOrderDetailExample example = new RefundOrderDetailExample();
				example.createCriteria().andIdIn(deleteIdList);
				refundOrderDetailMapper.deleteByExample(example);
			}
		}
		double applyJe = 0;
		String[] InfoArray = detailInfos.split(";");
		List<OrderDetail> orderDetails=new ArrayList<>();
		List<RefundOrderDetail> refundOrderDetails=new ArrayList<>();
		Integer waitSignNum=0;
		for(String info:InfoArray){
			String[] detail =info.split(",");
			Integer id=Integer.valueOf(detail[0]);
			Integer quantity = Integer.valueOf(detail[1]);
			RefundOrderDetail refundOrderDetail = refundOrderDetailMapper.selectByPrimaryKey(id);
			if(refundOrderDetail.getSignQuantity()>quantity){
				return -2;
			}
			waitSignNum+=quantity-refundOrderDetail.getSignQuantity();
			int num = refundOrderDetail.getQuantity()-quantity;
			if(num>0){
				OrderDetail orderDetail = orderDetailMapper.selectByPrimaryKey(refundOrderDetail.getOrderDetailId());
				Integer refundNum = orderDetail.getRefundQuantity()+num;
				if(refundNum>orderDetail.getQuantity()){
					return -3;
				}
				orderDetail.setRefundQuantity(refundNum);
				refundOrderDetails.add(refundOrderDetail);
				orderDetails.add(orderDetail);
			}else if(num<0){
				OrderDetail orderDetail = orderDetailMapper.selectByPrimaryKey(refundOrderDetail.getOrderDetailId());
				Integer refundNum = orderDetail.getRefundQuantity()+num;
				orderDetail.setRefundQuantity(refundNum);
				refundOrderDetails.add(refundOrderDetail);
				orderDetails.add(orderDetail);
			}
			refundOrderDetail.setEatablishUser(adminUser);
			refundOrderDetail.setEatablishTime(DateUtils.getNow());;
			applyJe+=refundOrderDetail.getBuyPrice().doubleValue()*quantity;
		}
		if(waitSignNum==0 && refundOrderDetails.size()>0){
			refundOrder.setStatus(Constant.Refund_Status_Wait_Refund);
			refundOrder.setStatusName(Constant.Refund_Status_Wait_Refund_Text);
		}
		refundOrder.setApplyJe(new BigDecimal(applyJe));
		refundOrder.setUpdatorName(adminUser);
		refundOrder.setUpdateTime(DateUtils.getNow());
		if(!StringUtils.isBlank(remark)){
			refundOrder.setRemark(remark);
		}
		int flag = refundOrderMapper.updateByPrimaryKeySelective(refundOrder);
		if(orderDetails.size()>0){
			for(OrderDetail detail:orderDetails){
				flag+=orderDetailMapper.updateByPrimaryKeySelective(detail);
			}
		}
		if(refundOrderDetails.size()>0){
			for(RefundOrderDetail detail:refundOrderDetails){
				flag+=refundOrderDetailMapper.updateByPrimaryKeySelective(detail);
			}
		}
		return flag;
	}
	

}
